﻿#include "OiPCH.hpp"
#include "OiToolCommand.hpp"
#include "OiCropCommand.hpp"

namespace Oi
{
    namespace PLScannerCore
    {
        BalanceCommand::BalanceCommand()
        {

        }

        void BalanceCommand::reto()
        {
            ToolPtrs tools = ToolViewer::OiToolViewer()->tools();
            for(auto& tool : tools)
            {
                tool->onLocation();
                tool->onCalculate();
            }
        }

        class CommandSystemImpl : public Impl<CommandSystem>
        {
        public:
            QVector<CommandPtr> _commands;
            int _maxList;
            bool _block;
        };

        CommandSystem::CommandSystem()
        {
            OI_I(CommandSystem);
            d->_maxList = 10;
            d->_block = false;
        }

        CommandSystem::~CommandSystem()
        {
            OI_E(CommandSystem);
            d->_commands.clear();
        }

        void CommandSystem::clear()
        {
            OI_F(CommandSystem);
            d->_commands.clear();
            emit redoInfo(false);
        }

        void CommandSystem::append(CommandPtr command)
        {
            OI_F(CommandSystem);

            if (!d->_block)
            {
                d->_commands.push_back(command);
                if(d->_commands.size() > d->_maxList)
                {
                    d->_commands.pop_front();
                }

                emit redoInfo(command->isRetoEnabled(), command->name());
            }
        }

        void CommandSystem::append(const int type, const QVariant& var)
        {
            OI_F(CommandSystem);

            CommandPtr command;

            switch(type)
            {
            case BalanceCommand::Tooldel:
            if(var.canConvert<ToolData>())
            {
                ToolData tooldata = var.value<ToolData>();
                command = CommandPtr(new ToolDelCommand(tooldata.toolType, tooldata.config));
            }
            break;

            case BalanceCommand::Crop:
            if(var.canConvert<int>())
            {
                command = CommandPtr(new CropCommand());
            }
            break;
            default:

            command = CommandPtr(new BalanceCommand());
            break;
            }

            if (command)
            {
                append(command);
            }
        }

        void CommandSystem::redo()
        {
            OI_F(CommandSystem);

            d->_block = true;

            if (d->_commands.size() > 0)
            {
                if(d->_commands.last()->isRetoEnabled())
                {
                    d->_commands.last()->reto();
                    d->_commands.pop_back();

                    emit redoInfo(d->_commands.size() > 0 ? d->_commands.last()->isRetoEnabled() : false,
                        d->_commands.size() > 0 ? d->_commands.last()->name() : QString());
                }
            }

            d->_block = false;
        }

        void CommandSystem::setMaxStorage(int maxValue)
        {
            OI_IMPL()->_maxList = maxValue;
        }

        int CommandSystem::maxStorage() const
        {
            return OI_IMPL()->_maxList;
        }

//         CommandSystem* CommandSystem::instance()
//         {
//             static CommandSystem commands;
//             return &commands;
//         }

    }
}
